﻿/*
Copyright © 2011 François Karman

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

See <license.txt> for the complete license of the software.
*/

using System;
using System.IO;

namespace Simple.Storage
{
    /// <summary>
    /// Defines the concept of serializer used to read/write data on a binary stream.
    /// </summary>
    public interface ISerializer
    {
        /// <summary>
        /// Checks if the serializer is associated to a specific type.
        /// </summary>
        /// <param name="type">The checked type.</param>
        /// <returns>
        /// <c>true</c> if the serializer can work with instances of <paramref name="type"/>;
        /// <c>false</c> otherwise.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="type"/> parameter is <c>null</c>.
        /// </exception>
        bool CanSerialize(Type type);

        /// <summary>
        /// Checks whether the <see cref="ISerializer.Deserialize(BinaryReader, Type, object)"/>
        /// method is implemented by this serializer.
        /// </summary>
        /// <param name="type">The checked type.</param>
        /// <returns>
        /// <c>true</c> if the serializer can work with initialized instances of
        /// <paramref name="type"/>; <c>false</c> otherwise.
        /// </returns>
        /// <remarks>
        /// This method should not return <c>true</c> when <see cref="ISerializer.CanSerialize"/>
        /// returns <c>false</c>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="type"/> parameter is <c>null</c>.
        /// </exception>
        bool CanWorkInPlace(Type type);

        /// <summary>
        /// Serializes a specified object as a binary stream.
        /// </summary>
        /// <param name="writer">
        /// The writer associated with the target stream.
        /// </param>
        /// <param name="type">
        /// The reference type for the serialization.
        /// </param>
        /// <param name="value">
        /// The serialized value - should be an instance of <paramref name="type"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// One of the <paramref name="writer"/> or <paramref name="type"/> parameters
        /// is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The <paramref name="value"/> is not an instance of <paramref name="type"/>.
        /// </exception>
        /// <exception cref="System.Runtime.Serialization.SerializationException">
        /// The <paramref name="value"/> can't be serialized.
        /// </exception>
        void Serialize(BinaryWriter writer, Type type, object value);

        /// <summary>
        /// Deserializes an object from a binary stream.
        /// </summary>
        /// <param name="reader">
        /// The reader associated with the source stream.
        /// </param>
        /// <param name="type">
        /// The reference type for the serialization.
        /// </param>
        /// <returns>
        /// The deserialized object.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="reader"/> parameter is <c>null</c>.
        /// </exception>
        /// <exception cref="System.Runtime.Serialization.SerializationException">
        /// The value can't be deserialized.
        /// </exception>
        object Deserialize(BinaryReader reader, Type type);

        /// <summary>
        /// Deserializes an object from a binary stream into an existing object.
        /// </summary>
        /// <param name="reader">
        /// The reader associated with the source stream.
        /// </param>
        /// <param name="type">
        /// The reference type for the serialization.
        /// </param>
        /// <param name="value">
        /// The container for the deserialized object.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// One of the parameters is <c>null</c>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The <paramref name="value"/> is not an instance of <paramref name="type"/>.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// This deserialization mode is not supported by the current implementation.
        /// </exception>
        /// <exception cref="System.Runtime.Serialization.SerializationException">
        /// The value can't be deserialized.
        /// </exception>
        /// <seealso cref="ISerializer.CanWorkInPlace"/>
        void Deserialize(BinaryReader reader, Type type, object value);
    }
}
